<template>
  <div class="filter-list flex-c">
    <slot name="filterItemLeft"></slot>
    <template v-for="(item, i) in filterList" :key="item.key">
      <div class="filter-item" v-if="!maxNum || i < maxNum">
        <template v-if="item.type == 'input_keyword'">
          <filterKeyword :currentItem="item" @search="searchKeyword($event, i)" />
        </template>
        <template v-else-if="item.type == 'input_keyword_type'">
          <filterKeywordByType :currentItem="item" @search="searchKeyword($event, i)" />
        </template>
        <template v-else-if="item.type == 'select_multiple'">
          <selectMultiple :key="item.key" :info="item" :defaultVal="item.value" @change="selectMulVal($event, item)" />
        </template>
        <template v-else-if="item.type == 'select'">
          <a-select v-model="item.value" :trigger-props="{ autoFitPopupMinWidth: true }" allow-search :style="{ width: item.width + 'px' }" :placeholder="item.placeholder || item.label" allow-clear :="item.attrs" @change="startSearch">
            <a-option v-for="(option, s) in item.optionItems" :key="s" :value="getOptionVal(item, option, 'value')" :label="getOptionVal(item, option, 'label')" />
          </a-select>
        </template>
        <template v-else-if="item.type == 'input_search'">
          <a-input-search v-model="item.value" :style="{ width: item.width + 'px' }" :placeholder="item.placeholder || item.label" allow-clear @press-enter="startSearch" @clear="startSearch" @search="startSearch" />
        </template>
        <template v-else-if="item.type == 'date_range'">
          <a-range-picker v-model="item.value" :="item.attrs" shortcuts-position="left" :shortcuts="rangeShortcuts(item.attrs ? item.attrs.valueFormat : 'YYYY-MM-DD')" :style="{ width: item.width + 'px' }" @change="startSearch" />
        </template>
        <template v-else-if="item.type == 'date_month'">
          <a-month-picker v-model="item.value" :="item.attrs" :style="{ width: item.width + 'px' }" @change="startSearch" />
        </template>
        <template v-else-if="item.type == 'keyword_date_range'">
          <filterDateRange :data="item" @search="startSearch" />
        </template>
        <template v-else-if="item.type == 'keyword_date_range_custom'">
          <filterDateRangeCustom :data="item" @search="startSearch" />
        </template>
        <template v-else-if="item.type == 'radio_btn'">
          <a-radio-group type="button" v-model="item.value">
            <a-radio v-for="(option, s) in item.optionItems" :key="s" :value="option.value">{{ option.label }}</a-radio>
          </a-radio-group>
        </template>
        <template v-else-if="item.type == 'sel_double'">
          <doubleSel :data="item" @search="doubleSelStartSearch(item)" />
        </template>
        <template v-else-if="item.type == 'cascader'">
          <filterCascader :data="item" @search="startSearch" />
        </template>
        <template v-else-if="item.type == 'cascader1'">
          <filterCascader1 :data="item" @search="startSearch" />
        </template>
        <template v-else-if="item.type == 'num_range'">
          <div class="price-range">
            <div>{{ item.label }}</div>
            <div>
              <a-input-number @blur="changePrice" hide-button v-model="item.value[0]" allow-clear :style="{ width: `${item.width}px` }" />
            </div>
            <div>
              <a-input-number @blur="changePrice" hide-button v-model="item.value[1]" allow-clear :style="{ width: `${item.width}px` }" />
            </div>
          </div>
        </template>
        <template v-else-if="item.type == 'num_range_type'">
          <div style="display: flex">
            <div>
              <a-select v-model="item.key" :trigger-props="{ autoFitPopupMinWidth: true }" @change="changeSelPrice">
                <a-option v-for="item1 of item.keyItems" :label="item1.label" :key="item1.value" :value="item1.value" />
              </a-select>
            </div>
            <div>
              <a-input-number @blur="changeSelPrice" hide-button v-model="item.value[0]" allow-clear :style="{ width: `${item.width}px` }" />
            </div>
            <div>
              <a-input-number @blur="changeSelPrice" hide-button v-model="item.value[1]" allow-clear :style="{ width: `${item.width}px` }" />
            </div>
          </div>
        </template>
      </div>
    </template>
    <!-- 气泡 -->
    <a-popover v-if="maxNum && maxNum > 0" trigger="click" ref="selectMulRef" position="bottom">
      <template #content>
        <template v-for="(item, i) in filterList" :key="item.key">
          <div class="filter-item" v-if="i >= maxNum">
            <template v-if="item.type == 'input_keyword'">
              <filterKeyword :currentItem="item" @search="searchKeyword($event, i)" />
            </template>
            <template v-else-if="item.type == 'select_multiple'">
              <selectMultiple :key="item.key" :info="item" :defaultVal="item.value" @change="selectMulVal($event, item)" />
            </template>
            <template v-else-if="item.type == 'select'">
              <a-select v-model="item.value" :trigger-props="{ autoFitPopupMinWidth: true }" allow-search :style="{ width: item.width + 'px' }" :placeholder="item.placeholder || item.label" allow-clear :="item.attrs" @change="startSearch">
                <a-option v-for="(option, s) in item.optionItems" :key="s" :value="getOptionVal(item, option, 'value')" :label="getOptionVal(item, option, 'label')" />
              </a-select>
            </template>
            <template v-else-if="item.type == 'input_search'">
              <a-input-search v-model="item.value" :style="{ width: item.width + 'px' }" :placeholder="item.placeholder || item.label" allow-clear @press-enter="startSearch" @clear="startSearch" @search="startSearch" />
            </template>
            <template v-else-if="item.type == 'date_range'">
              <a-range-picker v-model="item.value" :="item.attrs" shortcuts-position="left" :shortcuts="rangeShortcuts(item.attrs ? item.attrs.valueFormat : 'YYYY-MM-DD')" :style="{ width: item.width + 'px' }" @change="startSearch" />
            </template>
            <template v-else-if="item.type == 'date_month'">
              <a-month-picker v-model="item.value" :="item.attrs" :style="{ width: item.width + 'px' }" @change="startSearch" />
            </template>
            <template v-else-if="item.type == 'keyword_date_range'">
              <filterDateRange :data="item" @search="startSearch" />
            </template>
            <template v-else-if="item.type == 'keyword_date_range_custom'">
              <filterDateRangeCustom :data="item" @search="startSearch" />
            </template>
            <template v-else-if="item.type == 'radio_btn'">
              <a-radio-group type="button" v-model="item.value">
                <a-radio v-for="(option, s) in item.optionItems" :key="s" :value="option.value">{{ option.label }}</a-radio>
              </a-radio-group>
            </template>
            <template v-else-if="item.type == 'sel_double'">
              <doubleSel :data="item" @search="doubleSelStartSearch(item)" />
            </template>
            <template v-else-if="item.type == 'cascader'">
              <filterCascader :data="item" @search="startSearch" />
            </template>
            <template v-else-if="item.type == 'cascader1'">
              <filterCascader1 :data="item" @search="startSearch" />
            </template>
            <template v-else-if="item.type == 'num_range'">
              <div class="price-range">
                <div>{{ item.label }}</div>
                <div>
                  <a-input-number @blur="changePrice" hide-button v-model="item.value[0]" allow-clear :style="{ width: `${item.width}px` }" />
                </div>
                <div>
                  <a-input-number @blur="changePrice" hide-button v-model="item.value[1]" allow-clear :style="{ width: `${item.width}px` }" />
                </div>
              </div>
            </template>
            <template v-else-if="item.type == 'num_range_type'">
              <div style="display: flex">
                <div>
                  <a-select v-model="item.key" :trigger-props="{ autoFitPopupMinWidth: true }" @change="changeSelPrice">
                    <a-option v-for="item1 of item.keyItems" :label="item1.label" :key="item1.value" :value="item1.value" />
                  </a-select>
                </div>
                <div>
                  <a-input-number @blur="changeSelPrice" hide-button v-model="item.value[0]" allow-clear :style="{ width: `${item.width}px` }" />
                </div>
                <div>
                  <a-input-number @blur="changeSelPrice" hide-button v-model="item.value[1]" allow-clear :style="{ width: `${item.width}px` }" />
                </div>
              </div>
            </template>
          </div>
        </template>
      </template>
      <a-button class="gray-outline filter-item">
        <template #icon>
          <icon-filter />
        </template>
      </a-button>
    </a-popover>
    <div class="filter-item" v-if="isReset">
      <a-button @click="resetAll">重置</a-button>
    </div>
    <div class="filter-item" v-if="isSearch">
      <a-button type="primary" @click="startSearch">搜索</a-button>
    </div>
  </div>
  <!-- <div class="filter-result" v-if="resultTags.length > 0 && isShowTag">
    <a-space wrap>
      <a-tag v-for="item in resultTags" size="small" color="arcoblue" :closable="!item.undeletable" :key="item.key" @close="delTag(item)">
        <template v-if="!(item.tagVal instanceof Array && item.tagVal.length > 2)">
          <span> {{ item.label }}：</span>
          <p v-if="item.type != 'num_range' && item.type != 'num_range_type'">{{ item.tagVal instanceof Array ? item.tagVal?.join(',') : item.tagVal }}</p>
          <p v-else>{{ item.tagVal instanceof Array ? item.tagVal?.join('~') : item.tagVal }}</p>
        </template>
        <a-popover v-else position="bottom">
          <div class="flex-c">
            <span> {{ item.label }}：</span>
            <p>{{ item.tagVal[0] }}，{{ item.tagVal[1] }}等{{ item.tagVal.length }}项</p>
          </div>
          <template #content>
            <p v-for="(val, j) in item.tagVal" :key="j">{{ val }}</p>
          </template>
        </a-popover>
      </a-tag>
      <a-button type="text" style="color: #000430" v-if="resultTags.length > 1" size="mini" @click="clearAll">清除全部</a-button>
    </a-space>
  </div> -->
</template>
<script setup lang="ts">
  import { defineComponent, onMounted, PropType, reactive, ref, watchEffect, nextTick } from 'vue'
  import { FilterTableItem } from '@/types/components'
  import filterKeyword from '@/components/Form/filterKeyword.vue'
  import filterKeywordByType from '@/components/Form/filterKeywordByType.vue'
  import filterDateRange from './Form/filterDateRange.vue'
  import filterDateRangeCustom from './Form/filterDateRangeCustom.vue'
  import selectMultiple from './Form/selectMultiple.vue'
  import filterCascader from './Form/filterCascader.vue'
  import filterCascader1 from './Form/filterCascader1.vue'
  import doubleSel from './Form/doubleSel.vue'
  import { treeFindPath } from '@/utils/index'
  import dayjs from 'dayjs'
  import { cloneDeep } from 'lodash-es'
  import { rangeShortcuts } from '@/utils/timeFormat'
  const props = defineProps({
    filterItem: {
      type: Array as PropType<FilterTableItem[]>,
      default: () => [],
    },
    isReset: Boolean,
    maxNum: {
      type: Number,
    },
    isShowTag: {
      type: Boolean,
      default: true,
    },
    isSearch: {
      type: Boolean,
      default: false,
    },
  })

  interface keyOptionType {
    label: string
    value: string
  }

  const emit = defineEmits(['search'])
  // const originFilterList = toRef(props, 'filterItem')
  // 查询的参数
  let searchParam: any = {}
  let resultTags = ref<any>([])
  const filterList = reactive<FilterTableItem[]>([])
  const selectMulRef = ref()

  const searchKeyword = (searchVal: any, i: number) => {
    filterList[i].key = searchVal.code
    filterList[i].label = searchVal.label
    filterList[i].value = searchVal.value
    startSearch(searchVal)
  }
  // 批量选择数据
  const selectMulVal = (searchVal: any, item: any) => {
    item.value = searchVal
    startSearch()
  }

  const startSearch = (orginVal: any = {}) => {
    // 如果有筛选收起气泡窗口，则隐藏
    if (selectMulRef.value) {
      selectMulRef.value.handlePopupVisibleChange(false)
    }
    setResultTags()
    searchParam = {}
    filterList.forEach((el: FilterTableItem) => {
      if (el.type === 'keyword_date_range') {
        //多类型时间筛选
        searchParam.dataType = el.key
        searchParam.startDate = el.value instanceof Array ? el.value[0] : ''
        searchParam.endDate = el.value instanceof Array ? el.value[1] : ''
      } else if (el.type === 'input_keyword_type') {
        //关键词精确模糊
        searchParam.searchType = orginVal?.searchType
        searchParam.keyword = el.value
        searchParam.keywordType = el.key
      } else {
        searchParam[el.key] = el.value instanceof Array && el.type != 'date_range' ? el.value.join(',') : el.value
      }
    })

    if (!searchParam.startDate) {
      searchParam.dataType = ''
    }
    delete searchParam.priceType
    delete searchParam.priceMin
    delete searchParam.priceMax

    emit('search', searchParam)
  }
  // 获取查过结果显示的值
  const getTagVal = (item: FilterTableItem) => {
    //时间范围
    if ((item.type == 'date_range' || item.type == 'keyword_date_range') && item.value instanceof Array) {
      return item?.value?.map((str) => dayjs(str).format('YYYY-MM-DD'))?.join('~')
    }
    if (item.value instanceof Array) {
      return item.value.map((str: string) => {
        return enumVal(item.optionItems, item.optionField, str)
      })
    } else {
      return enumVal(item.optionItems, item.optionField, item.value)
    }
  }

  const getCascaderName = (el: any) => {
    let valKey = el?.attrs?.fieldNames?.value || 'id'
    let nameKey = el?.attrs?.fieldNames?.label || 'name'
    let arr: Array<string> = []
    if (el.value instanceof Array) {
      el.value.forEach((e: string) => {
        let arr1 = treeFindPath(el.optionItems, (data: any) => data[valKey] == e)
        arr.push(arr1[arr1.length - 1].name)
      })
    } else {
      let arr1 = treeFindPath(el.optionItems, (data: any) => data[valKey] == el.value)
      arr.push(arr1[arr1.length - 1][nameKey])
    }
    return arr
  }

  const setResultTags = () => {
    resultTags.value = []
    let arr: any = []
    filterList.forEach((el: FilterTableItem) => {
      let val: any = el.value
      let noVal = val === '' || val === null || val === undefined || (val instanceof Array && val.length === 0)

      if (!noVal && !el.isClear) {
        arr.push({
          ...el,
          tagVal: ['cascader', 'cascader1'].includes(el.type) ? getCascaderName(el) : getTagVal(el),
        })
      }
    })
    nextTick(() => {
      resultTags.value = arr
    })
  }

  const delTag = (data: any) => {
    let index = filterList.findIndex((el: FilterTableItem) => el.key == data.key)
    filterList[index].value = props.filterItem[index].undeletable ? props.filterItem[index].value : null
    startSearch()
  }

  const resetAll = () => {
    handleFilterList(props.filterItem)

    startSearch()
  }

  const clearAll = () => {
    filterList.forEach((el: FilterTableItem, index: number) => {
      el.value = props.filterItem[index].undeletable ? props.filterItem[index].value : null
    })

    startSearch()
  }

  const getOptionVal = (el: FilterTableItem, option: any, key: string) => {
    let _key = (el.optionField?.[key] || key) as string
    return option[_key]
  }

  const enumVal = (optionItems: any, optionField: any, str: any) => {
    if (!optionItems?.length) return str
    let valKey = optionField?.value || 'value'
    let labelKey = optionField?.label || 'label'
    let option = optionItems?.find((e: any) => str == e[valKey])
    return option?.[labelKey] || str
  }

  const handleFilterList = (list: Array<FilterTableItem>) => {
    filterList.length = 0
    filterList.push(...cloneDeep(props.filterItem))
  }

  const changePrice = () => {
    let obj: any = filterList.find((e) => e.type == 'num_range')
    let arr = obj?.value.filter((e: string) => e)

    if (arr.length == 2) {
      setResultTags()
      searchParam[obj.key] = obj.value.join(',')
      emit('search', searchParam)
    } else if (arr.length == 0) {
      obj.value = ref([])
      setResultTags()
      searchParam[obj.key] = obj.value.join(',')
      emit('search', searchParam)
    }
  }

  const changeSelPrice = () => {
    let obj: any = filterList.find((e) => e.type == 'num_range_type')
    let arr = obj?.value.filter((e: string) => e)
    if (arr.length == 2) {
      obj.label = obj.keyItems.find((e: any) => e.value == obj.key).label
      setResultTags()
      searchParam['priceType'] = obj.key
      searchParam['priceMin'] = arr[0]
      searchParam['priceMax'] = arr[1]
      emit('search', searchParam)
    } else if (arr.length == 0) {
      obj.value = ref([])
      setResultTags()
      delete searchParam.priceType
      delete searchParam.priceMin
      delete searchParam.priceMax
      emit('search', searchParam)
    }
  }

  const doubleSelStartSearch = (item: any) => {
    item.keyItems.forEach((e: keyOptionType) => {
      delete searchParam[e.value]
    })
    startSearch()
  }

  watchEffect(() => {
    handleFilterList(props.filterItem)
  })
  function changeOptions(index: number, list: Array<any>) {
    filterList[index].optionItems = list
  }
  defineExpose({ changeOptions })

  onMounted(() => {
    setResultTags()
  })
</script>
<script lang="ts">
  export default defineComponent({
    name: 'TableFilter',
  })
</script>

<style lang="less" scoped>
  .filter-item {
    margin-right: 8px;
    margin-bottom: 5px;
  }
  :deep(.arco-radio-group-button) {
    padding: 0;
    .arco-radio-button {
      margin: 0;
      background-color: #fff;
      line-height: 30px;
      border: 1px solid var(--color-border);
      &:first-child {
        border-radius: 5px 0 0 5px;
      }
      &:last-child {
        border-radius: 0 5px 5px 0;
      }
    }
    .arco-radio-checked {
      border-color: rgb(var(--primary-6));
    }
  }

  .filter-result {
    margin-bottom: 5px;
  }
  .filter-list {
    flex-wrap: wrap;
  }

  .price-range {
    display: flex;
    height: 32px;
    line-height: 32px;
    overflow: hidden;
    :deep(.arco-input-number-size-medium) {
      border: none;
    }
    border: 1px solid #dadde2;
    border-radius: 3px;
    div {
      &:nth-child(1) {
        padding: 0 8px;
        box-sizing: border-box;
        border-right: 1px solid #dadde2;
      }
      &:nth-child(2) {
        border-right: 1px solid #dadde2;
      }
    }
  }
</style>
